{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn import datasets\n",
    "\n",
    "iris = datasets.load_iris()\n",
    "X = iris.data[:, 2:]\n",
    "y = iris.target"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "DecisionTreeClassifier(class_weight=None, criterion='entropy', max_depth=2,\n",
       "                       max_features=None, max_leaf_nodes=None,\n",
       "                       min_impurity_decrease=0.0, min_impurity_split=None,\n",
       "                       min_samples_leaf=1, min_samples_split=2,\n",
       "                       min_weight_fraction_leaf=0.0, presort=False,\n",
       "                       random_state=None, splitter='best')"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.tree import DecisionTreeClassifier\n",
    "\n",
    "dt_clf = DecisionTreeClassifier(max_depth=2, criterion='entropy')\n",
    "dt_clf.fit(X, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_decision_boundary(model, axis):\n",
    "    x0, x1 = np.meshgrid(\n",
    "        np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1,1),\n",
    "        np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1,1)\n",
    "    )\n",
    "    X_new = np.c_[x0.ravel(), x1.ravel()]\n",
    "\n",
    "    y_predict = model.predict(X_new)\n",
    "    zz = y_predict.reshape(x0.shape)\n",
    "\n",
    "    from matplotlib.colors import ListedColormap\n",
    "    custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])\n",
    "\n",
    "    plt.contourf(x0, x1, zz, cmap=custom_cmap)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_decision_boundary(dt_clf, axis=[0.5, 7.5, 0, 3])\n",
    "plt.scatter(X[y==0,0],X[y==0,1])\n",
    "plt.scatter(X[y==1,0],X[y==1,1])\n",
    "plt.scatter(X[y==2,0],X[y==2,1])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 模拟使用信息熵进行划分"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def split(X, y, d, value):\n",
    "    index_a = (X[:,d] <= value)\n",
    "    index_b = (X[:,d] > value)\n",
    "    return X[index_a], X[index_b], y[index_a], y[index_b]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import Counter\n",
    "from math import log\n",
    "def entropy(y):\n",
    "    counter = Counter(y)\n",
    "    res = 0.0\n",
    "    for num in counter.values():\n",
    "        p = num / len(y)\n",
    "        res += -p * log(p)\n",
    "    return res\n",
    "    \n",
    "def try_split(X, y):\n",
    "    best_entropy = float('inf')\n",
    "    best_d, best_v = -1, -1\n",
    "    for d in range(X.shape[1]):\n",
    "        sorted_index = np.argsort(X[:,d])\n",
    "        for i in range(1, len(X)):\n",
    "            if X[sorted_index[i-1], d] != X[sorted_index[i], d]:\n",
    "                v = (X[sorted_index[i-1], d] + X[sorted_index[i], d]) / 2\n",
    "                x_l, x_r, y_l, y_r = split(X, y, d, v)\n",
    "                e = entropy(y_l) + entropy(y_r)\n",
    "                if e < best_entropy:\n",
    "                    best_entropy, best_d, best_v = e, d, v\n",
    "    return best_entropy, best_d, best_v"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "best_entropy =  0.6931471805599453\n",
      "best_d =  0\n",
      "best_v =  2.45\n"
     ]
    }
   ],
   "source": [
    "best_entropy, best_d, best_v = try_split(X, y)\n",
    "print(\"best_entropy = \", best_entropy)\n",
    "print(\"best_d = \", best_d)\n",
    "print(\"best_v = \", best_v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    " X1_l, X1_r, y1_l, y1_r = split(X, y, best_d, best_v)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.0"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "entropy(y1_l)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.6931471805599453"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "entropy(y1_r)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "best_entropy =  0.4132278899361904\n",
      "best_d =  1\n",
      "best_v =  1.75\n"
     ]
    }
   ],
   "source": [
    "best_entropy2, best_d2, best_v2 = try_split(X1_r, y1_r)\n",
    "print(\"best_entropy = \", best_entropy2)\n",
    "print(\"best_d = \", best_d2)\n",
    "print(\"best_v = \", best_v2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    " X2_l, X2_r, y2_l, y2_r = split(X1_r, y1_r, best_d2, best_v2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.30849545083110386"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "entropy(y2_l)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.10473243910508653"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "entropy(y2_r)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
